<template>
  <div v-loading="orderLoading" class="app-container">
    <audio
      controls
      :src="tipAudioSrc"
      id="__tm_audio_tip__"
      style="position: absolute; left: -999px; top: -999px; opacity: 0"
    />
    <p class="tips">
      请先在当前浏览器登录“拼多多跨境卖家中心”，期间保持登录状态
    </p>
    <div class="top-bar">
      <div>
        <el-select
          v-model="mallIds"
          placeholder="请选择 店铺"
          :disabled="startLoading"
          multiple
          @change="mallIdsChange"
        >
          <el-option
            v-for="item in mallList"
            :key="item.mallId"
            :label="item.mallName"
            :value="item.mallId + ''"
          />
        </el-select>
        <el-button
          :type="startLoading ? 'danger' : 'primary'"
          :loading="startLoading"
          :disabled="startLoading"
          @click="handleStart"
        >
          {{ robText }}
        </el-button>
        <el-button v-show="!startLoading" type="primary" @click="resetAddr">
          设置默认发货仓库
        </el-button>
        <el-button
          v-show="!startLoading"
          :icon="Setting"
          circle
          @click="robSetting"
        />
        <el-button v-show="startLoading" type="warning" @click="handleStop">
          停止抢仓
        </el-button>
      </div>
      <el-button
        type="success"
        :icon="CircleCheck"
        @click="successVisible = true"
      >
        抢仓成功列表 ({{ successList.length }})
      </el-button>
    </div>
    <div class="content">
      <el-table
        ref="robTableRef"
        :data="mallOrderList"
        border
        style="width: 100%; height: 800px"
        :row-class-name="setRowClass"
      >
        <el-table-column type="index" label="序号" width="80" />
        <el-table-column
          prop="subPurchaseOrderSn"
          label="备货单号"
          width="150"
        />
        <el-table-column label="商品信息">
          <template v-slot="{ row }">
            <div class="product-wrap">
              <img :src="row.productSkcPicture" alt="img" />
              <div>
                <span>备货母单号：{{ row.originalPurchaseOrderSn }}</span>
                <span>商品名称：{{ row.productName }}</span>
                <span>SKC：{{ row.productSkcId }}</span>
                <span>货号：{{ row.productSn }}</span>
              </div>
            </div>
          </template>
        </el-table-column>
        <el-table-column label="SKU信息">
          <template v-slot="{ row }">
            <div
              v-for="sku in row.skuQuantityDetailList"
              :key="sku.productSkuId"
              class="product-wrap"
            >
              <img :src="sku.thumbUrlList[0]" alt="img" />
              <div>
                <span>属性：{{ sku.className }}</span>
                <span>下单数量：{{ sku.purchaseQuantity }}</span>
                <span>SKU ID：{{ sku.productSkuId }}</span>
                <span>SKU 货号：{{ sku.goodsSkuId }}</span>
              </div>
            </div>
          </template>
        </el-table-column>
        <el-table-column label="发货仓库" width="300">
          <template v-slot="{ row }">
            <el-select
              :model-value="orderMapAddrId[row.subPurchaseOrderSn]"
              filterable
              :disabled="startLoading"
              @change="chooseAddress($event, row)"
            >
              <el-option
                v-for="addr in mapAddress(row)"
                :key="addr.id"
                :label="`(${addr.addressLabel}) ${addr.provinceName}/${addr.cityName}/${addr.districtName}, ${addr.addressDetail}`"
                :value="addr.id"
              />
            </el-select>
          </template>
        </el-table-column>
        <el-table-column label="抢仓状态" width="120">
          <template v-slot="{ row }">
            <el-button
              v-if="
                startLoading &&
                !notAllowedRobItem.includes(row.subPurchaseOrderSn)
              "
              loading
              type="warning"
              size="small"
            >
              抢仓中...
            </el-button>
            <el-button v-else type="info" size="small">未开始</el-button>
          </template>
        </el-table-column>
        <el-table-column label="操作" width="180px">
          <template v-slot="{ row }">
            <div class="handler-col">
              <el-button
                link
                type="primary"
                :disabled="startLoading"
                @click="handleSetting(row)"
              >
                {{
                  notAllowedRobItem.includes(row.subPurchaseOrderSn)
                    ? '取消屏蔽'
                    : '屏蔽抢仓'
                }}
              </el-button>
            </div>
          </template>
        </el-table-column>
      </el-table>
    </div>
    <el-dialog v-model="settingVisible" title="抢仓设置" width="500px">
      <div class="dialog-body">
        <el-form
          v-loading="settingLoading"
          :model="settingData"
          label-width="180px"
        >
          <el-form-item label="是否修改为最大发货数:">
            <el-radio-group v-model="settingData.is_create_by_max_num">
              <el-radio :label="true">是</el-radio>
              <el-radio :label="false">否</el-radio>
            </el-radio-group>
          </el-form-item>
          <el-form-item label="是否创建发货单:">
            <el-radio-group v-model="settingData.is_need_create">
              <el-radio :label="true">是</el-radio>
              <el-radio :label="false">否</el-radio>
            </el-radio-group>
          </el-form-item>
        </el-form>
      </div>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="settingVisible = false">关闭</el-button>
          <el-button @click="saveRobSetting" type="primary">保存</el-button>
        </span>
      </template>
    </el-dialog>
    <el-dialog
      v-model="successVisible"
      title="抢单成功列表"
      width="1200px"
      lock-scroll
    >
      <div class="dialog-body">
        <div class="top-bar"></div>
        <el-table
          ref="multipleTableRef"
          :data="successList"
          border
          style="width: 100%; height: 500px"
        >
          <el-table-column prop="subPurchaseOrderSn" label="备货单号" />
          <el-table-column label="商品信息">
            <template v-slot="{ row }">
              <div class="product-wrap">
                <img :src="row.productSkcPicture" alt="img" />
                <div>
                  <span>备货母单号：{{ row.originalPurchaseOrderSn }}</span>
                  <span>商品名称：{{ row.productName }}</span>
                  <span>SKC：{{ row.productSkcId }}</span>
                  <span>货号：{{ '' }}</span>
                </div>
              </div>
            </template>
          </el-table-column>
          <el-table-column label="SKU信息">
            <template v-slot="{ row }">
              <div
                v-for="sku in row.skuQuantityDetailList"
                :key="sku.productSkuId"
                class="product-wrap"
              >
                <img :src="sku.thumbUrlList[0]" alt="img" />
                <div>
                  <span>属性：{{ sku.className }}</span>
                  <span>下单数量：{{ sku.purchaseQuantity }}</span>
                  <span>SKU ID：{{ sku.productSkuId }}</span>
                  <span>SKU 货号：{{ sku.goodsSkuId }}</span>
                </div>
              </div>
            </template>
          </el-table-column>
        </el-table>
      </div>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="successVisible = false">关闭</el-button>
        </span>
      </template>
    </el-dialog>
    <el-dialog v-model="resetDialog" title="设置默认发货仓库" width="500px">
      <div class="dialog-body">
        <el-form :model="resetData" label-width="180px">
          <el-form-item
            v-for="(op, i) in resetOptions"
            :key="i"
            :label="`${op.mallName}:`"
          >
            <el-select v-model="resetData[op.mallId]" placeholder="请选择">
              <el-option
                v-for="addr in addrIdMapOrderList[op.mallId]"
                :key="addr.id"
                :label="`(${addr.addressLabel}) ${addr.provinceName}/${addr.cityName}/${addr.districtName}, ${addr.addressDetail}`"
                :value="addr.id"
              />
            </el-select>
          </el-form-item>
        </el-form>
      </div>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="resetDialog = false">关闭</el-button>
          <el-button type="primary" @click="saveMallAddr">保存</el-button>
        </span>
      </template>
    </el-dialog>
  </div>
</template>

<script setup>
import { computed, onMounted, onUnmounted, ref, watch } from 'vue'
import { useUserStore } from '@/store/user'
import { ElMessage as message } from 'element-plus'
import { CircleCheck, Setting } from '@element-plus/icons-vue'
import { difference } from 'lodash-es'
import {
  getRobConfig,
  getRobItemStatus,
  getRobOrderList,
  queryDeliveryAddressInfo,
  queryRobItemDeliveryAddressId,
  robState,
  setRobConfig,
  setRobItemDeliveryAddressId,
  setRobItemStatus,
  starRob,
  stopRob
} from '@/api/user'
import tipAudioSrc from '@/assets/tip.wav'

const userStore = useUserStore()
const sysUser = computed(() => userStore.sysUser)
const mallList = computed(() => {
  if (userStore.userInfo?.companyList && userStore.userInfo?.companyList[0]) {
    return userStore.userInfo.companyList[0].malInfoList
  } else {
    return []
  }
})
const audioRef = ref(null)
const mallIds = ref([])
const mallOrderList = ref([])
const startLoading = ref(false)
const successList = ref([])
const successVisible = ref(false)
const startTimer = ref(false)
const orderLoading = ref(false)
const settingData = ref({})
const settingVisible = ref(false)
const settingLoading = ref(false)
const robText = computed(() => {
  const validIds = mallOrderList.value.filter(
    (item) => !notAllowedRobItem.value.includes(item.subPurchaseOrderSn)
  )
  return startLoading.value
    ? `正在抢仓（${validIds.length}/${
        validIds.length + successList.value.length
      }）`
    : '开始抢仓'
})
const notAllowedRobItem = ref([])
const robTableRef = ref(null)

// mallId => [orderId...]
const mallIdMapOrderList = ref({})
// mallId => [addrId...]
const addrIdMapOrderList = ref({})
// orderId => addrId
const orderMapAddrId = ref({})
const resetDialog = ref(false)
const resetData = ref({})
const resetOptions = ref([])

const robSetting = async () => {
  settingVisible.value = true
  try {
    settingLoading.value = true
    const { is_create_by_max_num, is_need_create } = await getRobConfig()
    settingData.value = {
      is_create_by_max_num,
      is_need_create
    }
  } finally {
    settingLoading.value = false
  }
}
const saveRobSetting = async () => {
  await setRobConfig(settingData.value)
  settingVisible.value = false
  message.success('保存成功')
}

const mallIdsChange = async (ids) => {
  mallOrderList.value = []
  if (Array.isArray(ids) && ids.length === 0) return
  orderLoading.value = true
  try {
    let allList = []
    for await (let id of ids) {
      const res = await getOrderByMallId(id)
      mallIdMapOrderList.value[id] = res.map((it) => it.subPurchaseOrderSn)
      allList = [...allList, ...res]
    }
    mallOrderList.value = allList
  } finally {
    orderLoading.value = false
  }
}
const getOrderByMallId = async (id) => {
  const { result } = await getRobOrderList(id)
  return result || []
}

const handleStart = () => {
  if (sysUser.value.user_level === 0) return message.error('请先激活账号！')
  if (mallIds.value.length === 0) return message.error('请先选择店铺！')
  const bid = sysUser.value.bindMallIds || []
  const validBind = mallIds.value.some((sid) => {
    if (!bid.includes(sid)) return true
  })
  if (validBind) return message.error('请选择绑定该账号的店铺！')
  if (mallOrderList.value.length === 0) return message.error('无备货单数据！')
  audioRef.value.autoplay = true
  audioRef.value.pause()
  handleOccupy()
}
const handleStop = async () => {
  await stopRob()
  startLoading.value = false
  startTimer.value = false
}

// 检查抢仓状态
const getRobState = async () => {
  const { is_avaliable, mallId_list } = await robState()
  if (is_avaliable) {
    startLoading.value = true
    mallIds.value = mallId_list
    await mallIdsChange(mallId_list)
    handleStart()
  }
}
// 抢仓
const handleOccupy = () => {
  const orderIds = mallOrderList.value.map((o) => o.subPurchaseOrderSn)
  successList.value = []
  localStorage.setItem('__TEMU_OLD_IDS__', JSON.stringify(orderIds))
  localStorage.setItem('__TEMU_SUCCESS_LIST_LEN__', 0)
  startTimer.value = true
  starRob(mallIds.value).then(() => {
    startLoading.value = true
    loopCheckSucc()
  })
}
// 检查成功列表
const checkSuccess = async (ids) => {
  let newAllList = []
  for await (let id of ids) {
    const res = await getOrderByMallId(id)
    newAllList = [...newAllList, ...res]
  }

  const oldIds = mallOrderList.value.map((o) => o.originalPurchaseOrderSn)
  const newIds = newAllList.map((o) => o.originalPurchaseOrderSn)

  const reduceIds = difference(oldIds, newIds)
  const addIds = difference(newIds, oldIds)
  // 减少项（全部添加进成功列表）
  const reduceItems = mallOrderList.value.filter((o) =>
    reduceIds.includes(o.originalPurchaseOrderSn)
  )
  // 新增项
  const addItems = newAllList.filter((o) =>
    addIds.includes(o.originalPurchaseOrderSn)
  )
  // 未变动项
  const noChangeItems = mallOrderList.value.filter(
    (item) => !reduceIds.includes(item.originalPurchaseOrderSn)
  )

  console.log('减少的>>>>', reduceItems)
  console.log('新增的>>>>', addItems)
  console.log('未变动的>>>>', noChangeItems)
  // audioRef.value.play()

  const oldSuccLen =
    Number(localStorage.getItem('__TEMU_SUCCESS_LIST_LEN__')) || 0
  const newSuccLen = reduceItems.length + successList.value.length

  if (newSuccLen !== 0 && newSuccLen > oldSuccLen) {
    message.success('抢仓成功！')
    loopPlayAudio(newSuccLen - oldSuccLen)
    localStorage.setItem('__TEMU_SUCCESS_LIST_LEN__', newSuccLen)
  }
  successList.value = [...successList.value, ...reduceItems]
  mallOrderList.value = [...noChangeItems, ...addItems]

  if (mallOrderList.value.length === 0) {
    startTimer.value = false
    handleStop()
  }
}
// 屏蔽抢仓
const handleSetting = async (row) => {
  const id = row.subPurchaseOrderSn
  const val = notAllowedRobItem.value.includes(id) ? 0 : 1
  await setRobItemStatus([{ rob_id: id, set_status: val }])
  const ids = mallOrderList.value.map((o) => o.subPurchaseOrderSn)
  await queryRobItemStatus(ids)
}
const setRowClass = ({ row }) => {
  return notAllowedRobItem.value.includes(row.subPurchaseOrderSn)
    ? 'not-allowed'
    : ''
}
const queryRobItemStatus = async (ids) => {
  if (ids.length) {
    const { robStatusList } = await getRobItemStatus(ids)
    let notIds = []
    robStatusList.forEach((id, index) => {
      if (id == 1) {
        notIds.push(ids[index])
      }
    })
    notAllowedRobItem.value = notIds
  }
}
const queryOrderItemMapAddr = async () => {
  for (const mid of mallIds.value) {
    if (mallIdMapOrderList.value[mid]) {
      const { addressIdList } = await queryRobItemDeliveryAddressId(
        mid,
        mallIdMapOrderList.value[mid]
      )
      mallIdMapOrderList.value[mid].forEach((orderId, idx) => {
        orderMapAddrId.value[orderId] = addressIdList[idx]
      })
    }
  }
}
const saveMallAddr = async () => {
  const params = []
  Object.keys(resetData.value).forEach((mid) => {
    let orderIds = mallIdMapOrderList.value[mid]
    for (let i = 0; i < orderIds.length; i++) {
      if (orderMapAddrId.value[orderIds[i]] != resetData.value[mid]) {
        params.push({
          robId: orderIds[i],
          addressId: resetData.value[mid]
        })
      }
    }
  })
  await setRobItemDeliveryAddressId(params)
  Object.keys(resetData.value).forEach((mid) => {
    let orderIds = mallIdMapOrderList.value[mid]
    for (let i = 0; i < orderIds.length; i++) {
      orderMapAddrId.value[orderIds[i]] = resetData.value[mid]
    }
  })
  message.success('重置成功')
  resetDialog.value = false
}

// 地址相关
const mapAddress = (row) => {
  let itemMapMallId = {}
  let curId = row.subPurchaseOrderSn
  Object.keys(mallIdMapOrderList.value).map((k) => {
    mallIdMapOrderList.value[k].forEach((o) => {
      itemMapMallId[o] = k
    })
  })
  const curMallId = itemMapMallId[curId]
  return addrIdMapOrderList.value[curMallId]
}
const chooseAddress = async (val, row) => {
  orderMapAddrId.value[row.subPurchaseOrderSn] = val
  await setRobItemDeliveryAddressId([
    {
      robId: row.subPurchaseOrderSn,
      addressId: val
    }
  ])
}
const resetAddr = () => {
  resetOptions.value = mallList.value.filter((m) =>
    mallIds.value.includes(m.mallId + '')
  )
  resetOptions.value.forEach((mall) => {
    if (addrIdMapOrderList.value[mall.mallId]) {
      const item = addrIdMapOrderList.value[mall.mallId].find(
        (addr) => addr.isDefault
      )

      if (item) {
        resetData.value[mall.mallId] = item.id
      } else {
        resetData.value[mall.mallId] =
          addrIdMapOrderList.value[mall.mallId][0].id
      }
    }
  })
  resetDialog.value = true
}

watch(
  () => mallOrderList.value,
  async () => {
    const ids = mallOrderList.value.map((o) => o.subPurchaseOrderSn)
    await queryRobItemStatus(ids)
    for (let i = 0; i < mallIds.value.length; i++) {
      const { deliveryAddressInfo } = await queryDeliveryAddressInfo(
        mallIds.value[i]
      )
      addrIdMapOrderList.value[mallIds.value[i]] = deliveryAddressInfo
    }
    await queryOrderItemMapAddr()
  }
)

const sleep = (time) => {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve()
    }, time)
  })
}
const loopCheckSucc = async () => {
  await checkSuccess(mallIds.value)
  await sleep(3000)
  startTimer.value && (await loopCheckSucc())
}
const loopPlayAudio = async (count = 0) => {
  if (count && count > 0) {
    audioRef.value.play()
    count = count - 1
    await sleep(1000)
    await loopPlayAudio(count)
  }
}

onMounted(() => {
  startTimer.value = false
  getRobState()
  audioRef.value = document.getElementById('__tm_audio_tip__')
})

onUnmounted(() => {
  startTimer.value = false
})
</script>

<style scoped lang="scss">
.app-container {
  margin: 20px;
  padding: 20px;
  background-color: #fff;
}
.tips {
  color: red;
  margin-bottom: 12px;
}
.top-bar {
  margin-bottom: 12px;
  display: flex;
  justify-content: space-between;
}
:deep(.top-bar .el-select),
:deep(.top-bar .el-dropdown) {
  margin-right: 12px;
}
:deep(.el-table__row.not-allowed) {
  .el-table__cell:not(:last-child) {
    filter: grayscale(1);
    background: #cccccc;
    cursor: not-allowed;
  }
  .el-table__cell:last-child {
    background: #cccccc;
    .el-button {
      color: red;
    }
  }
}

.product-wrap {
  display: flex;
  align-items: center;
  margin-bottom: 15px;
  > img {
    width: 60px;
    height: 60px;
    flex-shrink: 0;
  }
  > div {
    display: flex;
    flex: 1;
    width: 100%;
    overflow: hidden;
    flex-direction: column;
    justify-content: center;
    padding: 0 12px;
    > span {
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
    }
  }
}
</style>
